Link to this headingSmart Contract Scanning

Blockchain Security 101

How Coinbase made a tool to automate Smart Contract Scanning

https://github.com/crytic/rattle
https://swcregistry.io/

Link to this headingCode Review Smart Contracts

Link to this headingEthereum Smart Contracts

https://consensys.github.io/smart-contract-best-practices/security-tools/

Example Bad Contracts:
https://swcregistry.io/
https://github.com/crytic/not-so-smart-contracts
https://github.com/smartbugs/smartbugs-wild
https://www.damnvulnerabledefi.xyz/
https://github.com/cclabsInc/BlockChainExploitation

Smart Contract Scanners:
https://github.com/crytic/medusa
https://github.com/crytic/slither
https://github.com/smartbugs/smartbugs
https://github.com/crytic/building-secure-contracts

Link to this headingSolana Smart Contracts

https://medium.com/coinmonks/how-to-audit-solana-smart-contracts-part-1-a-systematic-approach-56a434f6c9ed
https://medium.com/coinmonks/how-to-audit-solana-smart-contracts-part-2-automated-scanning-ceb88830ae6d

Paid Programs

Link to this headingSlither

Slither, the Solidity source analyzer

  • The installed solc version must be exactly the same as the version being used.

Run on a Token Address:

slither-check-erc 0x2A46f2fFD99e19a89476E2f62270e0a35bBf0756 DigitalMediaCore --erc ERC721 Installing '0.4.25'... Version '0.4.25' installed. WARNING:CryticCompile:Warning: crytic-export/etherscan-contracts/0x2A46f2fFD99e19a89476E2f62270e0a35bBf0756-DigitalMediaCore.sol:169:3: Warning: Defining constructors as functions with the same name as the contract is deprecated. Use "constructor(...) { ... }" instead. function Ownable() public { ^ (Relevant source part starts here and spans across multiple lines). Warning: crytic-export/etherscan-contracts/0x2A46f2fFD99e19a89476E2f62270e0a35bBf0756-DigitalMediaCore.sol:960:3: Warning: Defining constructors as functions with the same name as the contract is deprecated. Use "constructor(...) { ... }" instead. function ERC721Token(string _name, string _symbol) public { ^ (Relevant source part starts here and spans across multiple lines). Warning: crytic-export/etherscan-contracts/0x2A46f2fFD99e19a89476E2f62270e0a35bBf0756-DigitalMediaCore.sol:362:17: Warning: This function only accepts a single "bytes" argument. Please use "abi.encodePacked(...)" or a similar function to encode the data. require(keccak256(candidateCreatorRegistryStore.typeOfContract()) == keccak256("approvedCreatorRegistry")); ^-------------------------------------------------------^ Warning: crytic-export/etherscan-contracts/0x2A46f2fFD99e19a89476E2f62270e0a35bBf0756-DigitalMediaCore.sol:362:17: Warning: The provided argument of type string memory is not implicitly convertible to expected type bytes memory. require(keccak256(candidateCreatorRegistryStore.typeOfContract()) == keccak256("approvedCreatorRegistry")); ^-------------------------------------------------------^ # Check DigitalMediaCore ## Check functions [] balanceOf(address) is present [] balanceOf(address) -> () (correct return value) [] balanceOf(address) is view [] ownerOf(uint256) is present [] ownerOf(uint256) -> () (correct return value) [] ownerOf(uint256) is view [] safeTransferFrom(address,address,uint256,bytes) is present [] safeTransferFrom(address,address,uint256,bytes) -> () (correct return type) [] Transfer(address,address,uint256) is emitted [] safeTransferFrom(address,address,uint256) is present [] safeTransferFrom(address,address,uint256) -> () (correct return type) [] Transfer(address,address,uint256) is emitted [] transferFrom(address,address,uint256) is present [] transferFrom(address,address,uint256) -> () (correct return type) [] Transfer(address,address,uint256) is emitted [] approve(address,uint256) is present [] approve(address,uint256) -> () (correct return type) [] Approval(address,address,uint256) is emitted [] setApprovalForAll(address,bool) is present [] setApprovalForAll(address,bool) -> () (correct return type) [] ApprovalForAll(address,address,bool) is emitted [] getApproved(uint256) is present [] getApproved(uint256) -> () (correct return value) [] getApproved(uint256) is view [] isApprovedForAll(address,address) is present [] isApprovedForAll(address,address) -> () (correct return value) [] isApprovedForAll(address,address) is view [] supportsInterface(bytes4) is present [] supportsInterface(bytes4) -> () (correct return value) [] supportsInterface(bytes4) is view [] name() is present [] name() -> () (correct return value) [] name() is view [] symbol() is present [] symbol() -> () (correct return value) [] tokenURI(uint256) is present [] tokenURI(uint256) -> () (correct return value) ## Check events [] Transfer(address,address,uint256) is present [] parameter 0 is indexed [] parameter 1 is indexed [ ] parameter 2 should be indexed [] Approval(address,address,uint256) is present [] parameter 0 is indexed [] parameter 1 is indexed [ ] parameter 2 should be indexed [] ApprovalForAll(address,address,bool) is present [] parameter 0 is indexed [] parameter 1 is indexed

Run on a Single File:

slither tests/uninitialized.sol

Run on a Folder:

slither .

Run with Docker:

docker pull trailofbits/eth-security-toolbox docker run -it -v /home/share:/share trailofbits/eth-security-toolbox

Link to this headingEchidna

TODO: https://secure-contracts.com/program-analysis/echidna/exercises/Exercise-2.html

>>> bat testtoken.sol pragma solidity ^0.8.0; import "./token.sol"; /// @dev Run the template with /// ``` /// solc-select use 0.8.0 /// echidna program-analysis/echidna/exercises/exercise1/template.sol /// ``` contract TestToken is Token { address echidna = tx.origin; constructor() { balances[echidna] = 10_000; } function echidna_test_balance() public view returns (bool) { return balances[echidna] <= 10_000; } } >>> echidna testtoken.sol [2025-06-26 20:17:06.32] Compiling testtoken.sol... Done! (0.647776s) Multiple contracts found, only analyzing the first Analyzing contract: /Users/brian.ridings/Documents/echidna_tests/testtoken.sol:TestToken [2025-06-26 20:17:06.97] Running slither on testtoken.sol... Done! (0.767738s) echidna_test_balance: failed!💥 Call sequence: TestToken.transfer(0x10000,10001) Time delay: 487078 seconds Block delay: 57071 Traces: Unique instructions: 641 Unique codehashes: 1 Corpus size: 3 Seed: 642813754373980386 Total calls: 404

Link to this headingManticore

ERROR: This has been abandoned and has many bugs.

From Docker:

>>> docker pull trailofbits/manticore >>> docker run --rm -it -v $(pwd):/wd --name manticore-docker trailofbits/manticore bash root@5c1b5456ab44:/# solc-select install 0.8.25 Installing solc '0.8.25'... Version '0.8.25' installed. root@5c1b5456ab44:/# solc-select use 0.8.25 Switched global version to 0.8.25 root@5c1b5456ab44:/# manticore /wd/ExampleERC20.sol

Link to this headingPublished Bytecode on Blockchain

Getting Blocks from the Mainnet:

Blockchain Scanners: